import type { Metadata } from 'next'; import Link from 'next/link'; import { notFound } from 'next/navigation'; import { AdminTitle, Bool, JsonPre, Mono, StatusChip } from '@/components/admin/ui'; import { KeyValue } from '@/components/ui/key-value'; import { Unavailable } from '@/components/ui/unavailable'; import { adminApi, load, requireAdmin } from '@/lib/admin/admin-api'; import { fmtBytes, fmtDateTime, fmtInt } from '@/lib/format'; import { routes } from '@/lib/site'; export const metadata: Metadata = { title: 'Snapshot', robots: { index: false, follow: false } }; export const dynamic = 'force-dynamic'; /** Render the API's `diff` as change rows when it is a map/array of changes, otherwise as JSON. */ function Diff({ diff }: { diff: unknown }) { if (diff === null || diff === undefined) return

No diff (first snapshot or unchanged).

; const rows: { key: string; before: unknown; after: unknown }[] = []; if (Array.isArray(diff)) { for (const [i, it] of diff.entries()) { if (it && typeof it === 'object') { const o = it as Record; rows.push({ key: String(o.key ?? o.path ?? o.property ?? o.field ?? i), before: o.old ?? o.before ?? o.from ?? o.old_value, after: o.new ?? o.after ?? o.to ?? o.new_value }); } } } else if (typeof diff === 'object') { const o = diff as Record; const looksLikeMap = Object.values(o).every((v) => v && typeof v === 'object' && !Array.isArray(v) && ('old' in (v as object) || 'new' in (v as object) || 'before' in (v as object) || 'after' in (v as object))); if (looksLikeMap) { for (const [k, v] of Object.entries(o)) { const c = v as Record; rows.push({ key: k, before: c.old ?? c.before, after: c.new ?? c.after }); } } } if (!rows.length) return ; const show = (v: unknown) => (v === undefined || v === null ? — : {typeof v === 'string' ? v : JSON.stringify(v)}); return (
    {rows.map((r) => (
  • {r.key} {show(r.before)} {show(r.after)}
  • ))}
); } export default async function AdminSnapshotPage({ params }: { params: Promise<{ id: string }> }) { await requireAdmin(); const { id } = await params; const res = await load(adminApi.snapshot(id)); if (!res.ok && res.error.startsWith('404')) notFound(); if (!res.ok) { return ( <> ); } const s = res.data; return ( <>

← Documents · document

{s.id}}> Extraction debugger →

Structured extraction

Diff vs previous snapshot

Cleaned text excerpt {s.text_chars !== undefined && {fmtInt(s.text_chars)} chars{s.text_truncated ? ' · truncated at 20 kB' : ''}}

{s.text ? (
{s.text}
) : (

{s.text_error ? `Text unavailable: ${s.text_error}` : s.has_text === false ? 'No cleaned text for this snapshot (binary or JSON document).' : 'No text.'}

)}
); }